// generic_led.h
//
// Purpose: Declares the interface for a highly generalized LED control module.
// This module provides a framework for managing various types of LEDs (simple, RGB)
// with different behaviors (on/off, blink, static color) via a data-driven approach.
//
// System Thinking: Provides a reusable, hardware-agnostic LED subsystem.
// Module Thinking: Abstracts LED hardware and behavior into configurable objects,
//                  hiding all internal state and processing logic.
// Seamless Integration: Exposes configuration structs and API functions for
//                       initializing LEDs and controlling their state.
// Computational Thinking: Defines a data structure and API for dynamic LED management.

#ifndef GENERIC_LED_H
#define GENERIC_LED_H

#include "xgpiops.h" // For u32 (pin type)
#include <stdbool.h> // For bool type

// Forward declaration of the internal LED structure
typedef struct GenericLed GenericLed_t;

// Enum for LED types to differentiate between simple (monochrome) and RGB LEDs
typedef enum {
    LED_TYPE_MONOCHROME, // Single pin for ON/OFF
    LED_TYPE_RGB,        // Three pins for R, G, B
    // Add other types like PWM-controlled LEDs if needed
} LedType_t;

// Enum for simple ON/OFF states
typedef enum {
    LED_STATE_OFF = 0,
    LED_STATE_ON = 1,
} LedState_t;

// Structure to configure a single LED instance
// This is the data that external modules (like main or app_modules) will provide.
typedef struct {
    const char*     name;               // Unique name for the LED (e.g., "MIO_LD4", "EMIO_LD5")
    LedType_t       type;               // Type of LED (Monochrome or RGB)
    u32             pin_r_or_mono;      // Pin for Red channel or Monochrome LED
    u32             pin_g;              // Pin for Green channel (only for RGB)
    u32             pin_b;              // Pin for Blue channel (only for RGB)
    bool            active_low;         // True if LED lights up when pin is LOW
} GenericLedConfig_t;

// API functions for the generic LED module

/**
 * @brief Initializes the generic LED module.
 *        This function sets up the internal LED management structures and
 *        creates the FreeRTOS task responsible for periodic LED state updates.
 * @param led_configs An array of GenericLedConfig_t structures, detailing all LEDs to be managed.
 * @param num_leds The number of LED configurations in the array.
 * @return 0 on success, -1 on failure (e.g., task creation failed, too many LEDs).
 *
 * Computational Thinking: Orchestrates the setup of the generic LED subsystem.
 * System Thinking: Provides a single entry point for LED system initialization.
 */
int generic_led_init(const GenericLedConfig_t led_configs[], size_t num_leds);

/**
 * @brief Finds a registered LED instance by its name.
 * @param name The unique name of the LED.
 * @return Pointer to the GenericLed_t instance if found, NULL otherwise.
 *
 * Module Thinking: Provides a way to access specific LED objects without exposing internal details.
 */
GenericLed_t* GenericLed_GetByName(const char* name);

/**
 * @brief Turns a monochrome LED ON or OFF.
 * @param led_instance Pointer to the LED instance. Must be of type LED_TYPE_MONOCHROME.
 * @param state The desired state (LED_STATE_ON or LED_STATE_OFF).
 * @return 0 on success, -1 if LED type mismatch or instance is NULL.
 */
int GenericLed_SetMonochromeState(GenericLed_t* led_instance, LedState_t state);

/**
 * @brief Starts or stops a monochrome LED blinking.
 * @param led_instance Pointer to the LED instance. Must be of type LED_TYPE_MONOCHROME.
 * @param interval_ms The blinking interval in milliseconds. 0 to stop blinking.
 * @return 0 on success, -1 if LED type mismatch or instance is NULL.
 */
int GenericLed_SetMonochromeBlink(GenericLed_t* led_instance, u32 interval_ms);

/**
 * @brief Sets the color of an RGB LED.
 * @param led_instance Pointer to the LED instance. Must be of type LED_TYPE_RGB.
 * @param r Red component (0 or 1 for digital LEDs).
 * @param g Green component (0 or 1 for digital LEDs).
 * @param b Blue component (0 or 1 for digital LEDs).
 * @return 0 on success, -1 if LED type mismatch or instance is NULL.
 */
int GenericLed_SetRGBColor(GenericLed_t* led_instance, u8 r, u8 g, u8 b);

/**
 * @brief Starts or stops an RGB LED blinking with a specific color.
 * @param led_instance Pointer to the LED instance. Must be of type LED_TYPE_RGB.
 * @param interval_ms The blinking interval in milliseconds. 0 to stop blinking.
 * @param r Red component (0 or 1).
 * @param g Green component (0 or 1).
 * @param b Blue component (0 or 1).
 * @return 0 on success, -1 if LED type mismatch or instance is NULL.
 */
int GenericLed_SetRGBBlink(GenericLed_t* led_instance, u32 interval_ms, u8 r, u8 g, u8 b);

/**
 * @brief Gets the name of a registered LED instance.
 * @param led_instance Pointer to the LED instance.
 * @return The name string of the LED, or NULL if instance is invalid.
 *
 * Module Thinking: Provides a way to access the LED's name without exposing internal structure.
 */
const char* GenericLed_GetName(const GenericLed_t* led_instance);

#endif // GENERIC_LED_H
